#ifndef DIARYTOOL_SQL_TYPES_HPP
#define DIARYTOOL_SQL_TYPES_HPP

#define DATA_VERSION_MAJOR    5
#define DATA_VERSION_MINOR    0
#define DATA_VERSION_REVISION 0
#define MAKE_VERSION_CODE(MAJOR, MINOR, REVISION) (0x10000*(MAJOR) + 0x100*(MINOR) + (REVISION))
#define DATA_VERSION MAKE_VERSION_CODE(DATA_VERSION_MAJOR, DATA_VERSION_MINOR, DATA_VERSION_REVISION)
#define VERSION_MAJOR_PART(x) (((x) / 0x10000) & 0xFF)
#define VERSION_MINOR_PART(x) (((x) / 0x100) & 0xFF)
#define VERSION_REVISION_PART(x) ((x) & 0xFF)

static_assert(0 <= DATA_VERSION_MAJOR && DATA_VERSION_MAJOR <= 0xFF);
static_assert(0 <= DATA_VERSION_MINOR && DATA_VERSION_MINOR <= 0xFF);
static_assert(0 <= DATA_VERSION_REVISION && DATA_VERSION_REVISION <= 0xFF);

#include <cstdint>
#include <cstddef>
#include <string>
#include <vector>

/**
 * WARNNING: Changed Follow data type need change version info above!!!
 */

enum TagLevels
{
    L_PRIMARY = 0,
    L_SECONDARY = 1,
};

// for table tags
struct Tag {
    int32_t     tag_id;
    std::string tag_name;
    uint32_t    tag_color;
    uint32_t    tag_level; // ver 2.0.0
    bool        tag_disabled; // ver 4.0.0, tag can be disbaled and not show in editor
};

// for table redmine_activities
struct RedMineActivity {
    int32_t     act_id;
    std::string act_name;
};

// for table redmine_issues
struct RedMineIssue {
    int32_t         issue_id;
    std::string     issue_name;
    std::string     project_name;
    std::string     assigned_to;
    bool            is_closed;
};

// for table work_items
struct WorkItem {
    int32_t     work_id;
    double      hour;
    std::string comment;
    std::string note;
    std::string create_date;
    int32_t     act_id;
    int32_t     issue_id;
    int32_t     priority; // ver 5.0.0, add task priority for sort
    bool        is_uploaded;
};

// 优先级数字越小越高
#define PRIORITY_MIN 0
#define PRIORITY_MAX 9

// for table work_item_tags
struct WorkItemTag {
    int32_t     work_id;
    int32_t     tag_id;
};

// none entity
struct StatisticsResult
{
    struct TagTime
    {
        int32_t     tag_id;
        std::string tag_name;
        double      tag_time;

        std::vector<TagTime> sub_tags; // 这里是二级标签的耗时信息
    };

    std::string           date_start;
    std::string           date_end;
    double                total_time;
    std::vector<TagTime>  tags;         // 这里是一级标签的耗时信息
};

// version 3.0.0: add task table and time entry table

enum TaskStatus {
    ePaused     = 1,    // value use for ordering
    eInProgress = 0,
    eFinished   = 2,
};

struct WorkTask {
    int32_t              task_id;
    std::string          task_desc;
    std::string          create_date;
    int32_t              redmine_issue_id;
    int32_t              redmine_act_id;
    int32_t              status; // TaskStatus
    std::vector<int32_t> tags;
    uint32_t             display_color_rgba;
    int32_t              last_time_entry;
};

struct TimeEntry {
    int32_t     entry_id;
    int32_t     task_id;
    std::string begin_time;
    std::string end_time;
    int32_t     duration;
    int32_t     exported;
};

#endif // DIARYTOOL_SQL_TYPES_HPP
